Program Listing for File segengine.h
↰ Return to documentation for file (codes/cubicle_detect/darknet_ros/segengine.h
)
/*
This file is part of spixel.
Spixel is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Foobar is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "darknet_ros/stdafx.h"
#include "darknet_ros/structures.h"
#include "darknet_ros/tsdeque.h"
#include <map>
#define ADD_LEVEL_PARAM_DOUBLE(field, node, name) \
updateDouble[name] = [](SPSegmentationParameters& params, double val) { params.field = val; };\
AddLevelParamFromNodeDouble(node, name);
#define ADD_LEVEL_PARAM_INT(field, node, name) \
updateInt[name] = [](SPSegmentationParameters& params, int val) { params.field = val; };\
AddLevelParamFromNodeInt(node, name);
using namespace cv;
//using namespace std;
void UpdateFromNode(double& val, const FileNode& node);
void UpdateFromNode(int& val, const FileNode& node);
void UpdateFromNode(bool& val, const FileNode& node);
template <typename T>
void AddLevelParamFromNode(const FileNode& parentNode, const std::string& nodeName,
std::vector<std::pair<std::string, std::vector<T>>>& paramsList)
{
FileNode n = parentNode[nodeName];
if (n.empty()) return;
std::vector<T> levParams;
if (n.type() != FileNode::SEQ) {
levParams.push_back((T)n);
} else {
for (FileNode n1 : n) {
levParams.push_back((T)n1);
}
}
paramsList.push_back(std::pair<std::string, std::vector<T>>(nodeName, levParams));
}
struct SPSegmentationParameters {
int superpixelNum = 300; // Number of superpixels (the actual number can be different)
double appWeight = 1.0;
double regWeight = 1.0;
double lenWeight = 1.0;
double sizeWeight = 1.0;
double dispWeight = 2000.0; // \lambda_{disp}
double smoWeight = 0.2; // \lambda_{smo}
double smoWeightCo = 0.2; // \lambda_{smo}
double smoWeightHi = 0.2; // \lambda_{smo}
double priorWeight = 0.2; // \lambda_{prior}
double occPriorWeight = 15.0; // \lambda_{occ}
double hiPriorWeight = 5.0; // \lambda_{hinge}
double noDisp = 9.0; // \lambda_{d}
double inlierThreshold = 3.0;
int peblThreshold = 0; // planeEstimationBundaryLengthThreshold
double updateThreshold = 0.01;
int iterations = 1;
int maxUpdates = 400000;
int minPixelSize = 1;
int maxPixelSize = 16;
int reSteps = 10;
bool instantBoundary = false; // Boundary re-estimation on each step of iteration
bool stereo = false;
bool computeSGM = false;
bool batchProcessing = true;
bool inpaint = false; // use opencv's inpaint method to fill gaps in
// disparity image
bool debugOutput = false;
bool timingOutput = true;
int randomSeed = 0;
std::vector<std::pair<std::string, std::vector<double>>> levelParamsDouble;
std::vector<std::pair<std::string, std::vector<int>>> levelParamsInt;
std::map<std::string, std::function<void(SPSegmentationParameters&, double)>> updateDouble;
std::map<std::string, std::function<void(SPSegmentationParameters&, int)>> updateInt;
void SetLevelParams(int level);
void Read(const FileNode& node)
{
UpdateFromNode(superpixelNum, node["superpixelNum"]);
ADD_LEVEL_PARAM_DOUBLE(appWeight, node, "appWeight");
ADD_LEVEL_PARAM_DOUBLE(regWeight, node, "regWeight");
ADD_LEVEL_PARAM_DOUBLE(lenWeight, node, "lenWeight");
ADD_LEVEL_PARAM_DOUBLE(sizeWeight, node, "sizeWeight");
ADD_LEVEL_PARAM_DOUBLE(dispWeight, node, "dispWeight");
ADD_LEVEL_PARAM_DOUBLE(smoWeight, node, "smoWeight");
ADD_LEVEL_PARAM_DOUBLE(smoWeightCo, node, "smoWeightCo");
ADD_LEVEL_PARAM_DOUBLE(smoWeightHi, node, "smoWeightHi");
ADD_LEVEL_PARAM_DOUBLE(priorWeight, node, "priorWeight");
ADD_LEVEL_PARAM_DOUBLE(occPriorWeight, node, "occPriorWeight");
ADD_LEVEL_PARAM_DOUBLE(hiPriorWeight, node, "hiPriorWeight");
UpdateFromNode(noDisp, node["noDisp"]);
UpdateFromNode(stereo, node["stereo"]);
UpdateFromNode(computeSGM, node["computeSGM"]);
UpdateFromNode(batchProcessing, node["batchProcessing"]);
UpdateFromNode(inpaint, node["inpaint"]);
UpdateFromNode(instantBoundary, node["instantBoundary"]);
UpdateFromNode(iterations, node["iterations"]);
ADD_LEVEL_PARAM_INT(reSteps, node, "reSteps");
UpdateFromNode(inlierThreshold, node["inlierThreshold"]);
UpdateFromNode(maxUpdates, node["maxUpdates"]);
UpdateFromNode(minPixelSize, node["minPixelSize"]);
UpdateFromNode(maxPixelSize, node["maxPixelSize"]);
ADD_LEVEL_PARAM_INT(peblThreshold, node, "peblThreshold");
UpdateFromNode(updateThreshold, node["updateThreshold"]);
UpdateFromNode(debugOutput, node["debugOutput"]);
UpdateFromNode(timingOutput, node["timingOutput"]);
UpdateFromNode(randomSeed, node["randomSeed"]);
SetLevelParams(0);
}
private:
void AddLevelParamFromNodeDouble(const FileNode& parentNode, const std::string& nodeName)
{
AddLevelParamFromNode<double>(parentNode, nodeName, levelParamsDouble);
}
void AddLevelParamFromNodeInt(const FileNode& parentNode, const std::string& nodeName)
{
AddLevelParamFromNode<int>(parentNode, nodeName, levelParamsInt);
}
};
static void read(const FileNode& node, SPSegmentationParameters& x, const SPSegmentationParameters& defaultValue = SPSegmentationParameters());
class BInfoMatrix {
private:
BInfo** data;
int rows;
int cols;
public:
BInfoMatrix() : data(nullptr), rows(0), cols(0) { }
~BInfoMatrix() { Release(); }
void Resize(int _rows, int _cols)
{
Release();
rows = _rows;
cols = _cols;
data = new BInfo*[rows*cols];
memset(data, 0, sizeof(BInfo*)*rows*cols);
}
BInfo& operator ()(int r, int c) { return *(*data + r*cols + c); }
private:
void Release()
{
if (data != nullptr) {
BInfo* end = *data + rows*cols, *p = *data;
for (; p != end; p++) { if (p != nullptr) delete p; }
delete[] data;
}
}
};
class SPSegmentationEngine {
private:
struct PerformanceInfo {
double init = 0.0;
double imgproc = 0.0;
double ransac = 0.0;
std::vector<double> levelTimes;
std::vector<int> levelIterations;
double total = 0.0;
std::vector<double> levelMaxEDelta;
std::vector<int> levelMaxPixelSize;
};
PerformanceInfo performanceInfo;
// Parameters
SPSegmentationParameters params;
double planeSmoothWeight = 1; // Calculated from params in initialization
double planeSmoothWeightCo = 0.1;
double planeSmoothWeightHi = 0.1;
int initialMaxPixelSize; // Calculated in initialization
// Original image to process
Mat origImg;
// Depth image (required for stereo)
Mat1d depthImg;
Mat1d depthImgAdj;
// Image to process (in lab color space)
Mat img;
// Support structures
Matrix<Pixel> pixelsImg; // pixels matrix, dimension varies, depends on level
Matrix<Pixel*> ppImg; // matrix of dimension of img, pointers to pixelsImg pixels (for stereo)
std::vector<Superpixel*> superpixels;
public:
SPSegmentationEngine(SPSegmentationParameters params, Mat img, Mat depthImg = Mat());
virtual ~SPSegmentationEngine();
void ProcessImage();
// void ProcessImageStereo();
Mat GetSegmentedImage();
Mat GetSegmentedImagePlain();
// Mat GetSegmentedImageStereo();
Mat GetSegmentation() const;
// Mat GetDisparity() const;
std::string GetSegmentedImageInfo();
void PrintDebugInfo();
void PrintDebugInfo2();
std::vector<Superpixel*> GetSuperpixels();
// void PrintDebugInfoStereo();
void PrintPerformanceInfo();
int GetNoOfSuperpixels() const;
double ProcessingTime() { return performanceInfo.total; }
private:
void Initialize(Superpixel* spGenerator(int));
// void InitializeStereo();
// void InitializeStereoEnergies();
void InitializePPImage();
void UpdatePPImage();
int IterateMoves(int level);
// void ReEstimatePlaneParameters();
// void EstimatePlaneParameters();
bool SplitPixels(int& newMaxPixelSize);
void Reset();
void UpdateBoundaryData();
void UpdateBoundaryData2();
void UpdateInlierSums();
// void UpdatePlaneParameters();
// void UpdateStereoSums();
// void UpdateHingeStereoSums();
// void UpdateDispSums();
void DebugNeighborhoods();
void DebugBoundary();
void DebugDispSums();
bool TryMovePixel(Pixel* p, Pixel* q, PixelMoveData& psd);
// bool TryMovePixelStereo(Pixel* p, Pixel* q, PixelMoveData& psd);
int Iterate(Deque<Pixel*>& listD, Matrix<bool>& inList);
};
SPSegmentationParameters ReadParameters(const std::string& fileName, const SPSegmentationParameters& defaultValue = SPSegmentationParameters());